﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProgNetComponents.Data.SqlCe;
using System.Data;
using ProgNetComponentsDx.Browsers;
using System.IO;
using ProgNetComponentsDx.Options;
using System.Diagnostics;

namespace BuildHelper.BHTasks
{
    public class CheckOutUpdateTask : BaseProcesTask
    {
        public CheckOutUpdateTask()
        {
            AutoCreateFile = true;
            this.AlertImage = Properties.Resources.tortoise24;
            StopOnFirstError = false;
        }
        [SerializeProperty]
        public string Brancz { get; set; }
        [SerializeProperty]
        public bool IsCheckOut { get; set; }

        private int MaxApps;
        private int MaxDirs;
        private int CurApp;
        private int CurDir;
        string katalog = string.Empty;
        string gene = string.Empty;
        string apps = string.Empty;
        string svn = string.Empty;
        string svnUrl = string.Empty;
        Setup.Brancze.BranczeDataSet ds = new Setup.Brancze.BranczeDataSet();

        protected override string GetTaskName()
        {
           return (IsCheckOut ? "CheckOut " : "Update ") + Brancz;
        }
       
        protected override string GetAlertText()
        {
            string str = (IsCheckOut ? "CheckOut [" : "Update [") + Brancz + "]";
            if (IsCheckOut)
            {
                str = str.AppendLine("Katalog: " + CurDir + "/" + MaxDirs);
                str = str.AppendLine("App:" + CurApp + "/" + MaxApps);
            }
            return str;
        }

        protected override bool BeginTask()
        {
            bool res = base.BeginTask();
            
            if (res)
                res = ValidateCheckOut();
            if (res)
            {
                MaxApps = 0;
                MaxDirs = 0;
                CurApp = 0;
                CurDir = 0;
            }
            return res;
        }

        private bool ValidateCheckOut()
        {
            using (SqlCeDataManager sqlCeDataManager1 = new SqlCeDataManager())
            {
                ds.Clear();
                sqlCeDataManager1.FillTable(ds.STP_BRANCZE, "SELECT * FROM STP_BRANCZE WHERE STP_BR_NAZWA = " + Brancz.EscapeSql());
                sqlCeDataManager1.FillTable(ds.STP_BRANCZE_APPS, "SELECT * FROM STP_BRANCZE_APPS WHERE STP_BR_APP_BRANCZ = " + Brancz.EscapeSql());
                ds.AcceptChanges();
            }

            if (ds.STP_BRANCZE.Rows.Count == 1)
            {
                DataRow r = ds.STP_BRANCZE[0];
                katalog = r["STP_BR_KATALOG"].AsString().TrimEnd('\\');
                gene = katalog + "\\nd_src\\gene";
                apps = katalog + "\\nd_src\\gene\\apps";
                svn = r["STP_BR_SVN"].AsString();
                DataRow svnRow = BrowserCache.GetRowForValue(Init.InitFormBrowserNames.Statyczne.BranczeSVN, svn);
                if (svnRow.IsNull())
                {
                    FormMain.Instance.ShowDxErrorDialog("Nie można odnalećś url dla brancza.");
                    return false;
                }
                else{
                    svnUrl = svnRow["URL"].AsString().TrimEnd('/');
                }
                if (IsCheckOut)
                {
                    if (Directory.Exists(gene))
                    {
                        FormMain.Instance.ShowDxErrorDialog("Katalog gene istnieje. Nie można wykonać CheckOut.");
                        return false;
                    }
                    Directory.CreateDirectory(gene);
                }
                else
                {
                    if (!Directory.Exists(apps))
                    {
                        FormMain.Instance.ShowDxErrorDialog("Katalog apps nie istnieje. Nie można wykonać Update.");
                        return false;
                    }
                }
                return true;
            }
            else
            {
                FormMain.Instance.ShowDxErrorDialog("Nie można wybrać brancza.");
                return false;
            }
        }

        protected override void RunTask(Process Process)
        {
            List<string> systems = new List<string>();
            foreach (string sys in GlobalTools.Systems)
            {
                if (ds.STP_BRANCZE_APPS.SelectFirstRow("STP_BR_APP_APP = " + sys.EscapeSql()) != null)
                {
                    systems.Add(sys.ToLower());
                    if (sys == "GCM")
                        systems.Add("csm");
                }
            }

            string[] dirs = GlobalTools.TortoiseTools.GetDirectories(svnUrl);

            MaxDirs = dirs.Length - 1;//remove apps
            MaxApps = systems.Count;

            Process.CdDir(gene);
            GlobalTools.TortoiseTools.AddSvnToPath(Process);
            if (IsCheckOut)
                Process.Execute("svn co --depth files " + svnUrl + " .");
            else
            {
                if (OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Work_Group.Tortoise.AutoCleanup))
                    Process.Execute("svn cleanup");
                Process.Execute("svn up --non-interactive");
            }

            foreach (string dir in dirs)
            {
                if (!dir.XMatch("^apps$"))
                {
                    Process.Execute("svn up --set-depth infinity --non-interactive " + dir);
                }
            }
            if (IsCheckOut)
                Process.Execute("svn up --set-depth empty --non-interactive apps");
            foreach (string sys in systems)
            {
                Process.Execute("svn up --set-depth infinity --non-interactive apps/" + sys);
            }
            
        }

        protected override void ProcessMessage(string msg)
        {
            if (IsCheckOut)
            {
                if (msg.XMatch("svn up --set-depth infinity --non-interactive apps/"))
                {
                    CurApp++;
                    UpdateTaskInfo();
                }
                else if (msg.XMatch("svn up --set-depth infinity --non-interactive"))
                {
                    CurDir++;
                    UpdateTaskInfo();
                }
            }
        }

        protected override bool IsError(string msg)
        {
            if (IsCheckOut)
                return false;
            return msg.XMatch("^\\s*C\\s+");
        }
    }
}
